/**
 * 截断字符串并添加省略号
 * @param str 原始字符串
 * @param maxLength 最大长度
 * @param suffix 省略后缀，默认为'...'
 * @returns 截断后的字符串
 */
export const truncateString = (str: string, maxLength: number, suffix: string = '...'): string => {
  if (str.length <= maxLength) return str
  return str.substring(0, maxLength) + suffix
}

/**
 * 转义HTML特殊字符
 * @param str 原始字符串
 * @returns 转义后的字符串
 */
export const escapeHtml = (str: string): string => {
  const div = document.createElement('div')
  div.textContent = str
  return div.innerHTML
}

/**
 * 解析转义的HTML特殊字符
 * @param str 转义后的字符串
 * @returns 原始字符串
 */
export const unescapeHtml = (str: string): string => {
  const div = document.createElement('div')
  div.innerHTML = str
  return div.textContent || ''
}

/**
 * 生成随机字符串
 * @param length 字符串长度
 * @param chars 可选的字符集
 * @returns 随机字符串
 */
export const generateRandomString = (length: number, chars?: string): string => {
  const defaultChars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
  const charsSet = chars || defaultChars
  let result = ''
  const charsLength = charsSet.length
  for (let i = 0; i < length; i++) {
    result += charsSet.charAt(Math.floor(Math.random() * charsLength))
  }
  return result
}

/**
 * 格式化数字，添加千位分隔符
 * @param num 数字
 * @returns 格式化后的字符串
 */
export const formatNumber = (num: number): string => {
  return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',')
}

/**
 * 清理字符串中的多余空格
 * @param str 原始字符串
 * @returns 清理后的字符串
 */
export const cleanSpaces = (str: string): string => {
  return str.replace(/\s+/g, ' ').trim()
}

/**
 * 检查字符串是否为空或仅包含空格
 * @param str 要检查的字符串
 * @returns 是否为空或仅包含空格
 */
export const isEmptyString = (str: string | null | undefined): boolean => {
  return str === null || str === undefined || str.trim() === ''
}

/**
 * 首字母大写
 * @param str 原始字符串
 * @returns 首字母大写的字符串
 */
export const capitalizeFirstLetter = (str: string): string => {
  if (isEmptyString(str)) return str
  return str.charAt(0).toUpperCase() + str.slice(1)
}

/**
 * 驼峰命名转下划线命名
 * @param str 驼峰命名字符串
 * @returns 下划线命名字符串
 */
export const camelToSnake = (str: string): string => {
  return str.replace(/[A-Z]/g, letter => `_${letter.toLowerCase()}`)
}

/**
 * 下划线命名转驼峰命名
 * @param str 下划线命名字符串
 * @returns 驼峰命名字符串
 */
export const snakeToCamel = (str: string): string => {
  return str.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase())
}

/**
 * 计算字符串的相似度（Levenshtein距离算法）
 * @param str1 第一个字符串
 * @param str2 第二个字符串
 * @returns 相似度百分比
 */
export const calculateSimilarity = (str1: string, str2: string): number => {
  const distance = getLevenshteinDistance(str1, str2)
  const maxLength = Math.max(str1.length, str2.length)
  return (1 - distance / maxLength) * 100
}

/**
 * 获取Levenshtein距离
 * @param str1 第一个字符串
 * @param str2 第二个字符串
 * @returns 编辑距离
 */
const getLevenshteinDistance = (str1: string, str2: string): number => {
  const matrix = []
  let i, j

  // 处理边界情况
  if (str1.length === 0) return str2.length
  if (str2.length === 0) return str1.length

  // 初始化矩阵
  for (i = 0; i <= str2.length; i++) {
    matrix[i] = [i]
  }
  for (j = 0; j <= str1.length; j++) {
    matrix[0][j] = j
  }

  // 计算编辑距离
  for (i = 1; i <= str2.length; i++) {
    for (j = 1; j <= str1.length; j++) {
      if (str2.charAt(i - 1) === str1.charAt(j - 1)) {
        matrix[i][j] = matrix[i - 1][j - 1]
      } else {
        matrix[i][j] = Math.min(
          matrix[i - 1][j - 1] + 1, // 替换
          Math.min(
            matrix[i][j - 1] + 1, // 插入
            matrix[i - 1][j] + 1 // 删除
          )
        )
      }
    }
  }

  return matrix[str2.length][str1.length]
}

/**
 * 验证邮箱格式
 * @param email 邮箱地址
 * @returns 是否为有效的邮箱地址
 */
export const isValidEmail = (email: string): boolean => {
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
  return emailRegex.test(email)
}

/**
 * 验证URL格式
 * @param url URL地址
 * @returns 是否为有效的URL地址
 */
export const isValidUrl = (url: string): boolean => {
  try {
    new URL(url)
    return true
  } catch (e) {
    return false
  }
}